<?php

namespace App\Http\Controllers\Api\V1;

use Carbon\Carbon;
use EasyWeChat\Kernel\Exceptions\BadResponseException;
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
use EasyWeChat\OfficialAccount\Application;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;

class JsSdkController extends Controller
{
    public function jsSdk(Request $request)
    {
        $config = config('easywechat.official_account.default');
        // 检查缓存中是否已有 jsapi_ticket，如果有则直接返回
        if (Cache::has('jsapi_ticket')) {
            $jsapiTicket = Cache::get('jsapi_ticket');
        } else {
            try {
                $app = new Application($config);
            } catch (InvalidArgumentException $e) {
                return $this->failed($e->getMessage());
            }

            $api = $app->getClient();

            try {
                $response = $api->get('/cgi-bin/ticket/getticket', ['type' => 'jsapi']);

            } catch (\Exception|TransportExceptionInterface $e) {
                return $this->failed($e->getMessage());
            }

            try {
                $result = $response->toArray();
            } catch (BadResponseException|ClientExceptionInterface|DecodingExceptionInterface|ServerExceptionInterface|TransportExceptionInterface|RedirectionExceptionInterface $e) {
                return $this->failed($e->getMessage());
            }
            $jsapiTicket = $result['ticket'];

            // 将 jsapi_ticket 缓存到 Redis 中，有效期为 7000 秒（2 小时）
            Cache::put('jsapi_ticket', $jsapiTicket, 7000);
        }

        // 获取当前页面的 URL
        $url = $request->input('url');
        // 生成签名
        $timestamp = Carbon::now()->timestamp;
        $nonceStr  = md5(time());
        $signature = $this->generateSignature($jsapiTicket, $url, $timestamp, $nonceStr);

        // 返回 JS-SDK 参数
        return $this->success([
            'appId'     => $config['app_id'],
            'timestamp' => $timestamp,
            'nonceStr'  => $nonceStr,
            'signature' => $signature,
            'debug'     => config('app.debug'),

            'jsapiTicket' => $jsapiTicket,
            'url'         => $url,

            'jsApiList' => [
                'updateAppMessageShareData',
                'onMenuShareTimeline',
                'onMenuShareAppMessage',
                'onMenuShareQQ',
                'onMenuShareWeibo',
                'onMenuShareQZone',
            ],
        ]);
    }

    // 生成签名
    protected function generateSignature($jsapiTicket, $url, $timestamp, $nonceStr)
    {
        $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr&timestamp=$timestamp&url=$url";
        return sha1($string);
    }

}
